package com.globant.twittersearch;

import java.lang.ref.WeakReference;

import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;

import com.globant.adapter.TweetAdapter;
import com.globant.common.BusinessSettings;
import com.globant.common.MyApplication;
import com.globant.domain.SearchResponse;

public class MainActivity extends Activity {

	private final int ERROR_DIALOG = 1;
	private final int SEARCH_DIALOG = 2;
	
	private AsyncSearch asyncSearch;
	private TextView searchCriteria;
	private SearchResponse tweets;
	private String errorMsg;
	
	@Override
	protected void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
		outState.putCharSequence(BusinessSettings.SEARCH, searchCriteria.getText());
		outState.putSerializable(BusinessSettings.TWEETS, tweets);
		outState.putString(BusinessSettings.ERROR_MSG, errorMsg);
	}
	
	@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        searchCriteria = (TextView) findViewById(R.id.searchCriteria);
        
        if(savedInstanceState != null && savedInstanceState.containsKey(BusinessSettings.SEARCH)) {
        	searchCriteria.setText(savedInstanceState.getCharSequence(BusinessSettings.SEARCH));
        }
        
        if(savedInstanceState != null && savedInstanceState.containsKey(BusinessSettings.TWEETS)) {
        	tweets = (SearchResponse) savedInstanceState.getSerializable(BusinessSettings.TWEETS);
        	completeListView();
        }
        
        if(savedInstanceState != null && savedInstanceState.containsKey(BusinessSettings.ERROR_MSG)) {
        	errorMsg  = savedInstanceState.getString(BusinessSettings.ERROR_MSG);
        }
        
        addTextViewAction();
        
        asyncSearch = (AsyncSearch)getLastNonConfigurationInstance();
        
        if (asyncSearch != null) {
        	WeakReference<MainActivity> activity = new WeakReference<MainActivity>(this);
        	asyncSearch.attach(activity);
        }
    }
    
    private void completeListView() {
		TweetAdapter adaptador = new TweetAdapter(tweets.getResults());
		ListView tweetList = (ListView) findViewById(R.id.tweetList);
	
        LayoutInflater mInflater = (LayoutInflater) this.getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View footerView = mInflater.inflate(R.layout.listfooter, tweetList, false);
		
        TextView loadingTweets = (TextView) footerView.findViewById(R.id.loadingTweets);
        if(tweetList.getFooterViewsCount() == 0 && tweets.getNextPage() != null) {
        	tweetList.addFooterView(footerView);
        	loadingTweets.setOnClickListener(new OnClickListener() {
        	
        		@Override
        		public void onClick(View v) {
        			WeakReference<MainActivity> activity = new WeakReference<MainActivity>(MainActivity.this);
	    			asyncSearch = new AsyncSearch(activity, Boolean.TRUE);
					asyncSearch.execute();
        			
        		}
        	});
        }

        if(tweets.getNextPage() == null) {
        	loadingTweets.setEnabled(Boolean.FALSE);
        } else {
        	loadingTweets.setEnabled(Boolean.TRUE);
        }
        
        
		tweetList.setAdapter(adaptador);
    }
    
    private void dropListView() {
    	tweets = new SearchResponse();
		ListView tweetList = (ListView) findViewById(R.id.tweetList);
		tweetList.removeAllViewsInLayout();
    }
    
    private void addTextViewAction() {
    	searchCriteria.setOnEditorActionListener(new OnEditorActionListener() {
    		@Override
			public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
    			    			
    			if(v.getText() == null || v.getText().toString().length() == 0 
    					|| v.getText().toString().trim().length() == 0) {
					errorMsg = getResources().getString(R.string.blank_text);
					onCreateDialog(ERROR_DIALOG);
					showDialog(ERROR_DIALOG);
    			} else {
        			MyApplication application = (MyApplication) getApplication();
        			application.setSearch(v.getText().toString());
        			
	    			WeakReference<MainActivity> activity = new WeakReference<MainActivity>(MainActivity.this);
	    			asyncSearch = new AsyncSearch(activity, Boolean.FALSE);
					asyncSearch.execute();
    			}

				return false;
			}	
    	});
    }
    


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }
    
    @Override
    public Object onRetainNonConfigurationInstance() {
    	asyncSearch.detach();
    	return asyncSearch;
    }
    
    
    @Override
	public Dialog onCreateDialog(int id) {
    	
		Dialog dialog = new Dialog(this);
		dialog.setTitle(getResources().getString(R.string.app_name));
		
		if (id == ERROR_DIALOG) {
			dialog.setContentView(R.layout.error_dialog);
			TextView messageError = (TextView) dialog.findViewById(R.id.messageError);
			messageError.setText(errorMsg);
			
			Button ok = (Button) dialog.findViewById(R.id.ok);
			ok.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					dismissDialog(ERROR_DIALOG);
				}
			});
		} else {
			dialog.setContentView(R.layout.search_dialog);
			
			Button cancel = (Button) dialog.findViewById(R.id.cancel);
			cancel.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					if (asyncSearch != null && asyncSearch.getStatus() != AsyncTask.Status.FINISHED) {
						asyncSearch.cancel(true);
						dismissDialog(SEARCH_DIALOG);
					}
				}
			});
		}
		
		return dialog;
	}
    
    private class AsyncSearch extends AsyncTask<Void, Void, Void> {

		private MainActivity activity;
		private Boolean nextPage;

		public AsyncSearch(WeakReference<MainActivity> activity, Boolean nextPage) {
			this.nextPage = nextPage;
			attach(activity);
		}
		
		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			activity.onCreateDialog(SEARCH_DIALOG);
			activity.showDialog(SEARCH_DIALOG);
		}
		
		@Override
		protected Void doInBackground(Void... arg0) {
			TwitterConnection connection = new TwitterConnection();
			
			String criteria = searchCriteria.getText().toString();
			
			if(nextPage) {
				criteria = criteria.concat(tweets.getNextPage());
			}
			
			SearchResponse tweetsAsync = connection.obtainJson(criteria);
			
			if(tweets == null || !tweetsAsync.getQuery().contains(tweets.getQuery())) {
				tweets = tweetsAsync;
			} else {
				tweets.getResults().addAll(tweetsAsync.getResults());
				tweets.setNextPage(tweetsAsync.getNextPage());
			}
			
			return null;
		}
		
		@Override
		protected void onPostExecute(Void progress) {
			if(activity != null) {
				if(tweets != null && tweets.getResults() != null && 
						tweets.getResults().size() > 0) {
					activity.completeListView();
					activity.dismissDialog(SEARCH_DIALOG);
				} else {
					dropListView();
					errorMsg = getResources().getString(R.string.no_result);
					activity.dismissDialog(SEARCH_DIALOG);
					activity.onCreateDialog(ERROR_DIALOG);
					activity.showDialog(ERROR_DIALOG);
				}
			}
		}
		
		public void detach() {
			activity = null;
		}

		public void attach(WeakReference<MainActivity> activity) {
			this.activity = activity.get();
		}
    }
}
